package pure.engine.core 
{
	import flash.display.Shape;
    import flash.events.Event;
	import flash.utils.Dictionary;
    import flash.utils.getTimer;
	import pure.debug.Logger;
	import pure.engine.model.RenderManager;
	import pure.utils.DesU;
	import pure.engine.core.ns_despair;

	use namespace ns_despair;
	

	/**
	 * 进程管理器
	 * [Author] - PURE
	 * 
	 */
final public class ProcessManager
{

	
	
	//======================
	// Const
	//======================
	
	
	ns_despair static const INPUT:int    = 200;  // 输入
	ns_despair static const WORLD:int    =  80;  // 世界
	ns_despair static const MONITOR:int  =  30   // 监视器
	//ns_despair static const DELAY:int    =  10   // 延迟
	
	ns_despair static const ANIME:int    =  30;  // 动画
	ns_despair static const MOTION:int   =  10;  // 移动
	
	//ns_despair static const RENDER:int   =  -100   // 渲染
	
	
	
	/**
	 * 开始
	 */
	final public function start():void
	{
		if (m_started) 
		{
			Logger.reportWarning(this,'start',"进程机器，启动... !!");
			return;
		}
		
		m_started = true;
		
		trace('\n----------------------------------- [Process] -----------------------------------');
		Logger.reportMessage(this, "进程启动 !!");
		
		shape.addEventListener(Event.ENTER_FRAME, ____onEnterFrame, false, 10000, true);  // 此侦听器优先级最高...!!
	}
	
	
	/**
	 * 停止
	 */
	final public function stop():void
	{
		if (!m_started)
		{
			Logger.reportWarning(this, 'stop', "进程机器，已停止...");
			return;
		}
		
		m_started = false;
		m_oldTime = -1;
		Logger.reportMessage(this, "进程停止 !!");
		
		shape.removeEventListener(Event.ENTER_FRAME, ____onEnterFrame);
	}

	
	/**
	 * 加入计时侦听器
	 * 
	 * [Param] - listener  计时侦听器
	 * [Param] - priority  优先级
	 */
	final ns_despair function addTickListener(listener:ITickListener, priority:int = 0):void
	{
		if ((m_numTick++) + m_numFrame == 0)
		{
			start();
		}
		m_tickProcessor.addProcessListener(listener, priority, m_numTick);
	}


	/**
	 * 移除计时侦听器
	 * 
	 * [Param] - listener  计时侦听器
	 */
	final ns_despair function removeTickListener(listener:ITickListener):void
	{
		if ((--m_numTick) + m_numFrame == 0)
		{
			stop();
		}
		m_tickProcessor.removeProcessListener(listener);
	}
	
	
	/**
	 * 加入帧侦听器
	 * 
	 * [Param] - listener  逐帧侦听器
	 * [Param] - priority  优先级
	 */
	final ns_despair function addFrameListener(listener:IFrameListener, priority:int = 0):void
	{
		if (m_numTick + (m_numFrame++) == 0)
		{
			start();
		}
		m_frameProcessor.addProcessListener(listener, priority, m_numFrame);
	}
	
	
	/**
	 * 移除帧侦听器
	 * 
	 * [Param] - listener  逐帧侦听器
	 */
	final ns_despair function removeFrameListener(listener:IFrameListener):void
	{
		if (m_numTick + (--m_numFrame) == 0)
		{
			stop();
		}
		m_frameProcessor.removeProcessListener(listener);
	}
	


	
	
	
	//======================
	// Event
	//======================
	

	/**
	 * 逐帧
	 */
	final ns_despair function ____onEnterFrame(e:Event):void
	{
		var t:int = getTimer();
		
		// 初次跳过
		if (m_oldTime < 0)
		{
			m_oldTime = t;
			return;
		}
		
		// INPUT    -  200，输入状态，最先更新.
		// World    -   80，WorldBody(新模型加入，更新脏模型) → World，世界更新.
		// Monitor  -   30，监视器图层与残像更新，一次渲染
		// DELAY    -   10，延迟回调，最后更新.
		m_frameProcessor.advance(t - m_oldTime);
		
		// Motion   -   30，移动更新
		// Anime    -   10，动画更新
		m_tickProcessor.advance(t - m_oldTime);
		
		// Renderer -   二次渲染.
		RenderManager.updateAllDirtyRenderers();
		
		// DELAY
		//-----------------------
		// OTHER
		//-----------------------
		
		m_oldTime = t;
	}
	
	
	
	
	//======================
	// Member
	//======================
	

	ns_despair static var shape:Shape = new Shape();

	ns_despair static var instance:ProcessManager = new ProcessManager();
	
	ns_despair static var m_numTick:int, m_numFrame:int;
	
	ns_despair var m_oldTime:int = -1
	
	ns_despair var m_tickProcessor:IProcessor = new TickProcessor();
	
	ns_despair var m_frameProcessor:IProcessor = new FrameProcessor();

	ns_despair var m_started:Boolean;	// 是否已启动


}
}